package Busquedas;

import Estados.Estado;
import Juegos.Juego;
import java.util.ArrayList;

public class Voraz extends Busqueda {
    private final ArrayList<Estado> expandidos;
    private final ArrayList<Estado> pilaAbiertos;
    private boolean controlCiclos;
    private int contadorNodos;
    private long tiempoTotal;
	
	public Voraz(Estado ini,Juego juego) {
		super(ini,juego);
                this.expandidos=new ArrayList<Estado>();
                this.pilaAbiertos=new ArrayList<Estado>();
                pilaAbiertos.add(ini);
	}
	
	//@Override
	public ArrayList<Estado> resolver() {
            long tiempo1=System.currentTimeMillis();
            boolean solucion = false;
            while (!solucion && this.pilaAbiertos.size()!=0){
                int mejor = indiceMejor();
                Estado e=this.pilaAbiertos.remove(mejor);
                if(juego.esFinal(e)){
                    solucionar(e);
                    solucion=true;
                }
                else{
                    generaHijos(e);
                }
                long tiempo2=System.currentTimeMillis();
                tiempoTotal = tiempoTotal + (tiempo2 - tiempo1);
            }
            return this.solucion;
	}
	
	
	public int indiceMejor(){
            int indiceMejor = 0;
            int i = 0;
            int menorValor = pilaAbiertos.get(0).getHeuristica();
            while (i < pilaAbiertos.size()){
                    if (menorValor > pilaAbiertos.get(i).getHeuristica()){
                            indiceMejor = i;
                            menorValor = pilaAbiertos.get(i).getHeuristica();
                    }else{
                            i++;
                    }
            }
            return indiceMejor;
	}

        private boolean estaExpandido(Estado e){
            for(int i=0;i<this.expandidos.size();i++){
            if(e.Iguales(e, this.expandidos.get(i)))
                return true;
        }
        return false;
        }

        private void generaHijos(Estado e){
        this.expandidos.add(e);
        int ops=this.juego.getNumOperadores();
        for(int i=0;i<ops;i++){
            Estado nuevo=this.juego.operar(i,e);
            //control de ciclos y de estado peligro
            if( nuevo!=null && !estaExpandido(nuevo) && !juego.esPeligro(nuevo))
                this.pilaAbiertos.add(0, nuevo);
        }
    }
	
}
